package com.zdw.zfw.admin.modular.system.controller;

import com.google.common.collect.Maps;
import com.zdw.zfw.admin.core.constants.SysConstants;
import com.zdw.zfw.admin.core.util.JwtTokenUtil;
import com.zdw.zfw.admin.core.util.PasswordUtils;
import com.zdw.zfw.admin.core.util.ShiroUtils;
import com.zdw.zfw.admin.modular.system.model.entity.LoginUser;
import com.zdw.zfw.admin.modular.system.model.entity.SysUser;
import com.zdw.zfw.admin.modular.system.model.entity.SysUserRole;
import com.zdw.zfw.admin.modular.system.model.vo.LoginBean;
import com.zdw.zfw.admin.modular.system.service.ISysCaptchaService;
import com.zdw.zfw.admin.modular.system.service.ISysUserService;
import com.zdw.zfw.core.http.HttpResult;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * 登录控制器
 *
 * @author zdw
 * @date Oct 29, 2018
 */
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysLoginController {

	/**
	 * 用户service
	 */
	private final ISysUserService sysUserService;

	/**
	 * 验证码service
	 */
	private final ISysCaptchaService sysCaptchaService;

	private static final String CAPTCHA_TOKEN = "captcha_token";

	@GetMapping("captcha.jpg")
	public void captcha(HttpServletResponse response, HttpServletRequest request) throws IOException {
		sysCaptchaService.generateCaptcha(response, request);
	}

	/**
	 * 登录接口
	 */
	@PostMapping(value = "/login")
	public HttpResult login(@RequestBody LoginBean loginBean, HttpServletResponse response, @CookieValue(value = CAPTCHA_TOKEN, required = false) String cookie) {
		String userName = loginBean.getAccount();
		String password = loginBean.getPassword();
		String captcha = loginBean.getCaptcha();

		// 检查验证码
		String error = sysCaptchaService.checkCaptcha(cookie, captcha);
		if(!StringUtils.isEmpty(error)){
			return HttpResult.error(error);
		}

		// 用户信息
		SysUser user = sysUserService.findByName(userName);

		// 账号不存在、密码错误
		if (user == null) {
			return HttpResult.error("账号不存在");
		}

		// 账号锁定
		if (user.getStatus() == 0) {
			return HttpResult.error("账号已被锁定,请联系管理员");
		}

		if (!match(user, password)) {
			return HttpResult.error("密码不正确");
		}

		// 获取用户权限角色信息
		Set<String> permissions = sysUserService.findPermissions(userName);
		List<SysUserRole> userRoles = sysUserService.findUserRoles(user.getId());

		// 生成登录用户的非敏感信息存入 shiro 的 principal
		LoginUser loginUser = new LoginUser();
		BeanUtils.copyProperties(user, loginUser);
		loginUser.setUserRoles(userRoles);
		loginUser.setPermissions(permissions);

		// 生成jwt token 并设置claims
		HashMap<String, Object> claims = Maps.newHashMapWithExpectedSize(1);
		claims.put("user", loginUser);
		String token = JwtTokenUtil.generateToken(user.getId().toString(), claims);

		//将token作为响应头返回给客户端
		response.addHeader(SysConstants.TOKEN_HEADER, token);
		return HttpResult.success();
	}

	/**
	 * 登出接口
	 */
	@GetMapping(value = "/logout")
	public HttpResult logout() {
		ShiroUtils.logout();
		return HttpResult.success();
	}

	/**
	 * 验证用户密码
	 *
	 * @param user 用户实体
	 * @param password 密码
	 * @return 是否相同
	 */
	private boolean match(SysUser user, String password) {
		return user.getPassword().equals(PasswordUtils.encrypte(password, user.getSalt()));
	}
}